package com.pactera.asmp.server.service;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.pactera.asmp.server.common.constants.ResultCode;
import com.pactera.asmp.server.common.exception.CustomException;
import com.pactera.asmp.server.common.logprint.utils.StringUtils;
import com.pactera.asmp.server.dao.ProjectMapper;
import com.pactera.asmp.server.dao.ProjectModuleMapper;
import com.pactera.asmp.server.dao.ScriptInfoHistoryMapper;
import com.pactera.asmp.server.entity.ProjectModuleDTO;
import com.pactera.asmp.server.entity.ProjectModuleSearch;
import com.pactera.asmp.server.pojo.ProjectInfo;
import com.pactera.asmp.server.pojo.ScriptInfo;
import com.pactera.asmp.server.pojo.ScriptInfoHistory;
import com.pactera.asmp.server.pojo.User;
import com.pactera.asmp.server.utils.AssertUtil;
import com.pactera.asmp.server.utils.CompareUtil;
import com.pactera.asmp.server.utils.PageDataResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * @ProjectName: asmp-server
 * @Package com.pactera.asmp.server.service
 * @ClassName: ScriptInfoHistoryImpl
 * @Description: ScriptInfoHistoryImpl
 * @Date 2020/07/24 16:34
 * @Author lvzhiqiang
 * @Version 1.0
 */
@Service
@Slf4j
public class ScriptInfoHistoryImpl implements IScriptInfoHistoryService {
    @Resource
    private ScriptInfoHistoryMapper scriptInfoHistoryMapper;

    @Resource
    private ProjectModuleMapper projectModuleMapper;

    @Resource
    private ProjectMapper projectMapper;

    @Override
    public List<ScriptInfoHistory> select(ScriptInfoHistory scriptInfoHistory) {
        return scriptInfoHistoryMapper.select(scriptInfoHistory);
    }

    @Override
    public int insert(ScriptInfoHistory scriptInfoHistory) {
        return scriptInfoHistoryMapper.insert(scriptInfoHistory);
    }

    /**
     * @Description 整理老数据与新数据差异，并入库
     * @param scriptInfoOld 更新前数据
     * @param scriptInfoNew 更新后数据
     * @param status 1-新增, 2-修改，3-删除
     * @return
     */
    @Override
    public int handleParamAndInsert(ScriptInfo scriptInfoOld, ScriptInfo scriptInfoNew, Integer status) {
        User currUser = (User) SecurityUtils.getSubject().getPrincipal();
        if (null == currUser) {
            throw new CustomException(ResultCode.PERMISSION_EXPIRE);
        }
        AssertUtil.notNull(scriptInfoOld,"scriptInfoOld 参数不能为空");
        AssertUtil.notNull(scriptInfoNew,"scriptInfoNew 参数不能为空");

        // 把 projectModuleId 转成 projectId 等
        this.setProjectModuleInfo(scriptInfoNew);
        // 修改时前端未传该字段，主动赋值以避免记录变更
        if (StringUtils.isEmpty(scriptInfoNew.getDuid())) {
            scriptInfoNew.setDuid(scriptInfoOld.getDuid());
        }

        // 比较老数据与新数据差异
        Map<String, Object> map;
        try {
            map = CompareUtil.compareTwoClass(scriptInfoOld, scriptInfoNew);
        } catch (Exception e) {
            log.error("CompareUtil.compareTwoClass 反射未去除权限", e);
            throw new CustomException(ResultCode.SYSTEM_INNER_ERROR);
        }
        //整理数据入库
        // 删除脚本时，无新数据
        Integer scriptId = scriptInfoNew.getId();
        JSONObject scriptData = scriptInfoNew.getScriptData();
        if (null == scriptId) {
            scriptId = scriptInfoOld.getId();
        }

        ScriptInfoHistory scriptInfoHistory = new ScriptInfoHistory();
        scriptInfoHistory.setScriptId(scriptId);
        scriptInfoHistory.setScriptData(scriptData);
        scriptInfoHistory.setCreateTime(LocalDateTime.now());
        scriptInfoHistory.setUserId(currUser.getId());
        scriptInfoHistory.setUserName(currUser.getUsername());
        scriptInfoHistory.setStatus(status);
        scriptInfoHistory.setChangeInfo(new JSONObject(map));
        return scriptInfoHistoryMapper.insert(scriptInfoHistory);
    }

    @Override
    public PageDataResult selective(Integer scriptId, Integer page, Integer limit) {
        if (null == scriptId || 0 == scriptId) {
            throw new CustomException(ResultCode.PARAM_IS_BLANK);
        }
        PageHelper.startPage(page, limit);
        ScriptInfoHistory scriptInfoHistory = new ScriptInfoHistory();
        scriptInfoHistory.setScriptId(scriptId);
        List<ScriptInfoHistory> scriptInfoHistorys = scriptInfoHistoryMapper.select(scriptInfoHistory);

        PageDataResult pageDataResult = new PageDataResult();
        PageInfo<ScriptInfoHistory> pageInfo = new PageInfo<>(scriptInfoHistorys);
        pageDataResult.setTotals(Long.valueOf(pageInfo.getTotal()).intValue());
        pageDataResult.setList(scriptInfoHistorys);
        return pageDataResult;
    }

    @Override
    public int deleteByPrimaryKey(Integer id) {
        return scriptInfoHistoryMapper.deleteByPrimaryKey(id);
    }

    /**
     * 变更后的数据中，根据 projectModuleId 查询模块数据及项目数据
     * @param scriptInfoNew
     */
    private void setProjectModuleInfo(ScriptInfo scriptInfoNew) {
        Integer projectModuleId = scriptInfoNew.getProjectModuleId();
        if (null != projectModuleId && 0 != projectModuleId) {
            ProjectModuleSearch search = new ProjectModuleSearch();
            search.setId(projectModuleId);
            List<ProjectModuleDTO> projectModuleDTOs = projectModuleMapper.select(search);
            if (null != projectModuleDTOs && !projectModuleDTOs.isEmpty()) {
                ProjectModuleDTO projectModuleDTO = projectModuleDTOs.get(0);
                Integer projectId = projectModuleDTO.getProjectId();
                if (null != projectId) {
                    ProjectInfo projectInfo = projectMapper.selectByPrimaryKey(projectId);
                    if (null != projectInfo) {
                        scriptInfoNew.setProjectId(projectId);
                        scriptInfoNew.setProjcetName(projectInfo.getProjectName());
                    }
                }
                scriptInfoNew.setProModuleName(projectModuleDTO.getName());
            }
        }
    }
}
